#include "stdafx.h"
#include <math.h>
#include "ValidatorObj.h"
#include "CombatCard.h"
#include "Utility.h"


void TObjValidators::OnArchieveReaded()
{
	m_vValidators.clear();
	if(m_iID==INVALID_ID) return ;
	if(m_tiAliveOrDead!=eTriple_Null)
	{
		VObj_AliveState* pV=new VObj_AliveState();
		pV->InitData(m_tiAliveOrDead==eTriple_True);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vHasSkills.empty())
	{
		VObj_SkillCheck* pV=new VObj_SkillCheck();
		pV->InitData(m_vHasSkills);
		pV->SetInclude(true);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vNotHasSkills.empty())
	{
		VObj_SkillCheck* pV=new VObj_SkillCheck();
		pV->InitData(m_vNotHasSkills);
		pV->SetInclude(false);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vHasSkillInCategorys.empty())
	{
		VObj_SkillCatgegoryCheck * pV=new VObj_SkillCatgegoryCheck();
		pV->InitData(m_vHasSkillInCategorys);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vRaceIn.empty())
	{
		VObj_RaceCheck* pV=new VObj_RaceCheck();
		pV->InitData(m_vRaceIn);
		pV->SetInclude(true);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vRaceNotIn.empty())
	{
		VObj_RaceCheck* pV=new VObj_RaceCheck();
		pV->InitData(m_vRaceNotIn);
		pV->SetInclude(false);
		Add(TValidatorObjPtr(pV));
	}
	if(m_iFightTurnEqual!=INVALID_ID)
	{
		VObj_FightTurnEqual* pV=new VObj_FightTurnEqual();
		pV->InitData(m_iFightTurnEqual);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vObjTypeIn.empty())
	{
		VObj_ObjTypeCheck* pV=new VObj_ObjTypeCheck();
		pV->InitData(m_vObjTypeIn);
		pV->SetInclude(true);
		Add(TValidatorObjPtr(pV));
	}
	if(!m_vObjTypeNotIn.empty())
	{
		VObj_ObjTypeCheck* pV=new VObj_ObjTypeCheck();
		pV->InitData(m_vObjTypeNotIn);
		pV->SetInclude(false);
		Add(TValidatorObjPtr(pV));
	}
	if(m_tiHpFullOrNot!=eTriple_Null)
	{
		VObj_HpFullCheck* pV=new VObj_HpFullCheck();
		pV->InitData(m_tiHpFullOrNot==eTriple_True);
		Add(TValidatorObjPtr(pV));
	}
	if(m_eHpCompare!=eCompare_Null)
	{
		VObj_HpCheck* pV=new VObj_HpCheck();
		pV->InitData(m_eHpCompare,m_iHpAbsValue,m_fPercentValue);
		Add(TValidatorObjPtr(pV));
	}
	if(m_iEachValidorFacedCard>0)
	{
		VObj_FacedObjCheck* pV=new VObj_FacedObjCheck();
		pV->InitData(m_iEachValidorFacedCard);
		Add(TValidatorObjPtr(pV));
	}

	if(!m_vObjInStorages.empty())
	{
		VObj_StorageIn* pV=new VObj_StorageIn();
		pV->InitData(m_vObjInStorages);
		Add(TValidatorObjPtr(pV));
	}
}



bool VObj_AliveState::Validate( CombatObj * pObj ) const
{
	if(m_bBeAliveOrDead)
	{
		return (pObj->GetHp()>0);
	}
	else
	{
		return (pObj->GetHp()==0);
	}
}


bool VObj_SkillCheck::Validate( CombatObj * pObj ) const
{
	std::vector<int32> vHasSkill=pObj->GetSkillTypeList();
	return Util::RangeCheckRange(m_bIncludeOrExclude,vHasSkill,m_vSkillTypes);
}

bool VObj_SkillCatgegoryCheck::Validate( CombatObj * pObj ) const
{
	std::vector<const ReactorTypeDef* > vHasSkillTypeDefs=pObj->GetSkillTypeDefList();
	for(uint32 ii=0;ii<vHasSkillTypeDefs.size();ii++)
	{
		const ReactorTypeDef* pSkillType=vHasSkillTypeDefs[ii];
		if(NULL==pSkillType) continue;
		bool bFit=true;
		for(uint32 kk=0;kk<m_vSkillCatgegorys.size();kk++)
		{
			if(!Util::RangeCheckID(true,m_vSkillCatgegorys[kk],pSkillType->m_vCategorys))
			{
				bFit=false;
				break;
			}
		}
		if(bFit) return true;
	}
	return false;
}



bool VObj_RaceCheck::Validate( CombatObj * pObj ) const
{
	return Util::RangeCheckID(m_bIncludeOrExclude,pObj->GetRace(),m_vRaces);
}

bool VObj_FightTurnEqual::Validate( CombatObj * pObj ) const
{
	return pObj->GetFightTurn()==m_iTurnNum;
}



bool VObj_ObjTypeCheck::Validate( CombatObj * pObj ) const
{
	return Util::RangeCheckID(m_bIncludeOrExclude,pObj->GetObjType(),m_vTypes);
}



bool VObj_HpFullCheck::Validate( CombatObj * pObj ) const
{
	if(m_bHpFullOrNot)
	{
		return pObj->GetHp()>=pObj->GetHpMax();
	}
	else
	{
		return pObj->GetHp()<pObj->GetHpMax();
	}
}



bool VObj_HpCheck::Validate( CombatObj * pObj ) const
{
	switch(m_eCompare)
	{
	case eCompare_Greater:
		{
			if(m_iValue>=0) return pObj->GetHp()>m_iValue;
			if(m_fPercent>=0) return (pObj->GetHp()*1.f/(pObj->GetHpMax()*1.f))>m_fPercent;
			
		}break;
	case eCompare_Less:
		{
			if(m_iValue>=0) return pObj->GetHp()<m_iValue;
			if(m_fPercent>=0) return (pObj->GetHp()*1.f/(pObj->GetHpMax()*1.f))<m_fPercent;
		}break;
	case eCompare_Equal:
		{
			if(m_iValue>=0) return pObj->GetHp()==m_iValue;
			if(m_fPercent>=0) return fabs((pObj->GetHp()*1.f/(pObj->GetHpMax()*1.f)) - m_fPercent ) < 1e-6;
		}break;
	default:
		return true;
	}
	return true;
}

void VObj_FacedObjCheck::InitData( int32 iEacheValidator )
{
	m_iEacheValidator=iEacheValidator;
	m_pEachValidator=ValidatorEachManager::Instance().LookupItem(m_iEacheValidator);
}

bool VObj_FacedObjCheck::Validate( CombatObj * pObj ) const
{
	if(NULL==m_pEachValidator) return true;
	CombatObj * pFacedObj=pObj->GetFacedObj();
	if(NULL==pFacedObj) return false;
	return m_pEachValidator->Validate(pObj,pFacedObj);
}

bool VObj_StorageIn::Validate( CombatObj * pObj ) const
{
	if(m_vStorageIn.size()==0) 
		return true;
	if(pObj->GetObjType()!=ECombatObj_Card)
		return true;
	
	ECardStorage eStorage=((CombatCard *)pObj)->GetStorage();
	for(uint32 ii=0;ii<m_vStorageIn.size();ii++)
	{
		if(m_vStorageIn[ii]==eStorage) 
			return true;
	}
	return false;
}